/*
 * This class is designed to search difference matching to annotations with
 * same or crossed spans; Differences in markable category(class), complex
 * relationships or simple attributes will be figure out and marked with
 * read wavy underline.
 */

package ResultEditor.Conflicts;

import ResultEditor.Annotations.Depot;
import java.io.File;
import java.util.Vector;
import ResultEditor.Annotations.Article;
import ResultEditor.Annotations.Annotation;
import javax.swing.JTextPane;

/**
 * This class is designed to search difference matching to annotations with
 * same or crossed spans; Differences in markable category(class), complex
 * relationships or simple attributes will be figure out and marked with
 * read wavy underline.
 *
 *
 * @author  Jianwei Chris Leng,
 *          Nov 2, 2010,
 *          Division of Epidemiolofy, School of Medicine, University of Utah.
 */
public class DifferentMatching {

    public static Vector<Diff> depot_DifferentMatching = new Vector<Diff>();
    protected JTextPane textcomp;
    Thread thisthread = null;

    public DifferentMatching(JTextPane comp){
        this.textcomp = comp;
    }

    public void clear(){
        depot_DifferentMatching.clear();
        try{
            if(textcomp!=null){
                // remove all existing wave underlines
                ResultEditor.UnderlinePainting.HighlightPainter painter
                    = new ResultEditor.UnderlinePainting.HighlightPainter(this.textcomp);
                painter.RemoveAllWaveHighlight();
            }
        }catch(Exception ex){}
    }

    /**
     * Primary method of class "DifferentMatching". This method is used to search
     * and find difference matching: cross overlap spans, or exact overlap spans.
     */
    public void search_differentMatching(final File curr_f){

        try{if( thisthread != null ){
            //thisthread.getAllStackTraces().clear();
            thisthread.interrupt();
        }}catch(Exception ex){}

            thisthread = new Thread(){
                @Override
                public void run(){
                    clear();

                    if ((curr_f == null)||(curr_f.getName()==null))
                        return;

                    if(!env.Parameters.enabled_Diff_Display){
                        return;

                    }
                                        
                    findRepetitive(curr_f);

                    checkFounds_forUnique();

                    drawDiff_inWaveLine();

                }};
            thisthread.start();
    }

    

    /**
     * Check for difference matching to these annotations with same overlapped
     * or cross-spans. Propoal is to find difference in their class, complex
     * relationships or normal attributes.
     *
     * @param   curr_f
     *          File of Current handling text source. It can be used to indentfy
     *          which "article" contains annotations for current document in
     *          depot of annotations.
     */
    public void findRepetitive(File curr_f){
        try{

        

            // ##1## get the depot of all annotations
            ResultEditor.Annotations.Depot depot = new ResultEditor.Annotations.Depot();
            if (depot==null)   return;

            // ##2## get annotations of current document
            Article article = Depot.getArticleByFilename(curr_f.getName().trim());
            if (article ==  null)   return;
            if( article.annotations == null ) return;
            int size = article.annotations.size();


            // ##3## go over all annotations in current document
            for(int i=0; i< size; i++) {
                Annotation annotation = article.annotations.get(i);
                if (annotation==null)
                    continue;
                int x = annotation.spanstart;
                int y = annotation.spanend;

                for( int j=0; j<size; j++ ){
                    if (i==j)   continue;
                    Annotation compare_annotation = article.annotations.get(j);
                    if(compare_annotation == null)
                        continue;

                    /**check for exact same spans*/
                    if(env.Parameters.DifferenceMatching.checkSameOverlappingSpan){
                        if((compare_annotation.spanstart==x)&&(compare_annotation.spanend==y)) {
                            depot_DifferentMatching.add(new Diff( annotation.annotationText , x, y, 1));
                            continue;
                        }
                    }

                    /**check for overlap spans*/
                    if( env.Parameters.DifferenceMatching.checkCrossSpan ){

                        // one big span contains a smaller span
                        if(( x<compare_annotation.spanstart )&&(y>compare_annotation.spanend)){
                            depot_DifferentMatching.add(new Diff( "" , compare_annotation.spanstart, compare_annotation.spanend, 3));
                            continue;
                        }

                        if(( x>compare_annotation.spanstart )&&(y<compare_annotation.spanend)){
                            depot_DifferentMatching.add(new Diff( "" , x, y, 3));
                            continue;
                        }


                        // two span crossed each other
                        if( ( compare_annotation.spanend > x )&&(  compare_annotation.spanend < y )&&(compare_annotation.spanend>compare_annotation.spanstart) ) {
                            
                            if(compare_annotation.spanstart<x)
                                depot_DifferentMatching.add(new Diff( "" , x, compare_annotation.spanend, 2));
                            else
                                depot_DifferentMatching.add(new Diff( "" , compare_annotation.spanstart, compare_annotation.spanend, 2));
                            
                            continue;
                        }else if( ( compare_annotation.spanstart > x )&&(  compare_annotation.spanstart < y )&&(compare_annotation.spanend>compare_annotation.spanstart) ) {

                            if(compare_annotation.spanend>y)
                                depot_DifferentMatching.add(new Diff( "" , compare_annotation.spanstart, y, 2));
                            else
                                depot_DifferentMatching.add(new Diff( "" , compare_annotation.spanstart, compare_annotation.spanend, 2));

                            continue;
                        }
                    }


                }
            }
            
        }catch(Exception ex){
        }
    }

    

    /**make sure only unique diff can be stored after pervious draft searching.*/
    private void checkFounds_forUnique(){
        try{
            if ((depot_DifferentMatching==null)||(depot_DifferentMatching.size()<1))
                return;

            int size = depot_DifferentMatching.size();
            for(int i=size-1; i>=0; i-- ){
                Diff diff = depot_DifferentMatching.get(i);

                for(int j=i-1; j>=0; j-- ){
                    Diff compare_diff = depot_DifferentMatching.get(j);
                    if ((diff.spanstart==compare_diff.spanstart)
                        &&(diff.spanend==compare_diff.spanend)){
                        depot_DifferentMatching.remove(i);
                        break;
                    }
                }
            }

        }catch(Exception ex){
            System.out.println("error 1010281728::"+ex.toString());
        }
    }

    private void drawDiff_inWaveLine(){
        try{
            // remove all existing wave underlines
            ResultEditor.UnderlinePainting.HighlightPainter painter
                = new ResultEditor.UnderlinePainting.HighlightPainter(this.textcomp);
            painter.RemoveAllWaveHighlight();

            if(( depot_DifferentMatching == null)||( depot_DifferentMatching.size()<1))
                return;

            for(Diff diff: depot_DifferentMatching){
                painter.addNewWavelineHightlight(diff.spanstart, diff.spanend);
                //System.out.println("start: " + diff.spanstart + "/ end: "+ diff.spanend);
            }

            
        }catch(Exception ex){
            System.out.println("error 1011011451: fail to show wave underline" +
                    " to indicate these different matching annotations.");
        }

    }

}


